#include <cmath>
#include <iostream>
#include <fstream>
#include <cstdlib>

#include "Erathostene.hpp"
#include <gmpxx.h>

using namespace std;

Erathostene::Erathostene(int inSize)
{
   _size       = inSize;
   _tab        = new bool[_size + 1];
   _nbPremier  = new mpz_class [_size];
   _nbDeNbPremiers = 0;
}

void Erathostene::remplissage()
{
   _tab[0] = 0;
   for(int i = 1 ; i <= _size ; i++)
   {
      _tab[i] = 1;
   }
}

void Erathostene::sieve()
{
   int i, j;
   for(i = 2 ; i <= (int)sqrt(_size) ; i++)
   {
      if(_tab[i])
      {
         for(j = i*i ; j <= _size ; j += i)
         {
            _tab[j] = 0;
         }
      }
   }
}

void Erathostene::erathostene()
{
   int i, j;
   
   j = 0;
   
   for(i = 0 ; i <= _size ; i++)
   {
      if(_tab[i])
      {
         _nbPremier[j] = i;
         j++;
      }
   }
   
   _nbDeNbPremiers = j;
}


mpz_class * Erathostene::execution()
{
   this->remplissage();
   this->sieve();
   this->erathostene();
   
   return _nbPremier;
}

mpz_class Erathostene::higherFactor(mpz_class & nb)
{
   mpz_class n = nb;
   int i = 0;
   
   if(n != 1)
   {
      i = 1;
      while (n != 1)
      {
         if(mpz_divisible_p(n.get_mpz_t(), _nbPremier[i].get_mpz_t()))
         {
            n = n / _nbPremier[i];
         }
         else i++;
      }
   }
   
   return _nbPremier[i];
}

void Erathostene::generateFile()
{
   ofstream fic;
   
   fic.open("nombresPremiers", ios::out);
   
   if(fic.bad())
   {
      exit(-1);
   }
   
   // Remplissage des nombres premiers
   for(int i = 0 ; i < _nbDeNbPremiers ; i++)
   {
      fic << _nbPremier[i] << endl;
   }
   
   fic.close();
}
